import platform = require('../common/baseCommon');
import appCommon = require('../common/appCommon');


/**
 * 模块名称
 */
const moduleName = "platform.client";

//解决IE浏览器兼容
// 为string增加 startWith方法
if (!String.prototype.startsWith) {
    String.prototype.startsWith = function (searchString, position) {
        return this.substr(position || 0, searchString.length) === searchString;
    };
}
// 为string增加 endsWith方法
if (!String.prototype.endsWith) {
    String.prototype.endsWith = function (searchString, position) {
        return this.substr(this.length - position || 0 - searchString.length, searchString.length) === searchString;
    };
}
// 为string增加 compare方法,不区分大小写匹配
if (!String.prototype.compare) {
    String.prototype.compare = function (str: string) {
        if (!this || !str) return false;
        //不区分大小写
        if (this.toLocaleUpperCase() == str.toLocaleUpperCase()) {
            return true; // 正确
        }
        else {
            return false; // 错误
        }
    }
}

/**
* 错误代码：文件找不到,Not Found
*/
const errorCode_FileNotFound = 404;


/**
* 请求类型
*/
type requestType = "GET" | "POST";

//******************远程******************//
/**
    * 创建JsonAjax设置
    * @param url url
    * @param serviceName 服务名称
    * @param functionName 方法名称
    * @param args 参数
    */
function createJsonAjaxSettings(url: string, serviceName: string, functionName: string, args: any[]): JQueryAjaxSettings {
    let settings: JQueryAjaxSettings = {};
    let header: platform.remoteHeader;
    if (platform.currentUser) {
        header = {
            userToken: platform.currentUser,
            userID: platform.currentUser.name,
            password: platform.currentUser.password
        }
    }
    /** 设置请求头 */
    if (args && args[0] && (args[0] instanceof platform.RequestMessage)) {
        let requestMessage: platform.RequestMessage<any> = <platform.RequestMessage<any>>args[0];
        requestMessage.header.userToken = platform.currentUser;
    }
    settings.url = url;
    settings.type = "POST";
    settings.dataType = "json";
    /** 发送信息前设置类型信息 */
    settings.data = JSON.stringify({
        serviceName: serviceName,
        functionName: functionName,
        header: header,
        args: args
    });
    //暂不采用这个方式传输报文头
    // let request: platform.remoteRequest = new platform.remoteRequest();
    // request.serviceName = serviceName;
    // request.functionName = functionName;
    // request.args = args;
    // settings.data = platform.addonSerialize(request);
    return settings;
}

/**
    * 同步json调用
    * @param url 服务地址
    * @param serviceName 服务名称
    * @param functionName 方法名称
    * @param args 参数
    */
export function jsonCall(url: string, serviceName: string, functionName: string, args?: any[]): any {
    let settings: JQueryAjaxSettings = createJsonAjaxSettings(url, serviceName, functionName, args);
    let returnValue: any;
    let errMessage: any;
    settings.async = false;
    settings.crossDomain = true;
    settings.success = (response) => {
        returnValue = response;
        if (returnValue) {
            // 返回值处理前要获取类型原型
            platform.fetchAddonProtoType(returnValue);
        }
    };
    settings.error = (xhr, status, err) => {
        errMessage = platform.addonSerialize(xhr);
    };
    $.ajax(settings);
    if (returnValue)
        return returnValue.d;
    if (errMessage) {
        throw new Error(errMessage);
    }
    return undefined;
}

/**
    * 异步json调用
    * @param url 服务地址
    * @param serviceName 服务名称
    * @param functionName 方法名称
    * @param args 参数
    */
export function asyncJsonCall(url: string
    , serviceName: string
    , functionName: string
    , args?: any[]
    , success?: (result: any) => void
    , error?: (err: Error) => void) {
    let settings: JQueryAjaxSettings = createJsonAjaxSettings(url, serviceName, functionName, args);
    settings.async = true;
    //settings.crossDomain = true;
    settings.success = (response) => {
        let returnValue = response;
        if (returnValue) {
            // 返回值处理前要获取类型原型
            platform.fetchAddonProtoType(returnValue);
        }
        if (success) {
            if (returnValue) {
                // 处理返回值
                success(returnValue.d);
            } else {
                success(undefined);
            }
        }
    };
    settings.error = (xhr, status, err) => {
        if (error) {
            error(new Error(JSON.stringify(xhr)));
        }
    };
    $.ajax(settings);
}

/**
* 脚本库列表
*/
let scriptLibs: string[] = [];

/**
* 动态加载JavaScript 库
* @param url 待加载库的url
* @param forceToDuplicateLoad 强制重新加载
* @remark url必须是../开头的相对地址
*/
export function loadScript(url: string, forceToDuplicateLoad: boolean = false) {
    /** 非强行加载 */
    if (!forceToDuplicateLoad && scriptLibs[url]) {
        return;
    }

    $.ajax({
        url: url,
        dataType: "script",
        async: false,
        success: (scr, status, xhr) => {
            // Execute JavaScript
            eval(scr);
            scriptLibs.push(url);
        },
        error: (xhr, status, err) => {
            // The JavaScript File not Found
            if (xhr.status == errorCode_FileNotFound)
                return;
            // Other Error Status
            else
                throw new Error(`${url}脚本加载异常, 状态码: ${xhr.status} , 错误描述 : ${err}`);
        }
    });
}

/**
    * 动态加载JavaScript库集
    * @param scripts
    */
export function loadScripts(scripts: string[]) {
    for (var script of scripts) {
        loadScript(script);
    }
}

/**
    * 动态加载 css 文件
    * @param url 待加载css文件的url
    * @param type 
    * @param rel
    */
export function loadStyle(url: string) {
    loadLink(url, "text/css", "stylesheet");
}

/**
    * 动态加载 css 文件集
    * @param urls css文件集url
    */
export function loadStyles(urls: string[]) {
    for (var url of urls) {
        loadStyle(url);
    }
}

/**
    * 动态加载Json
    * @param url 待加载Json的url
    * @remark url必须是../开头的相对地址
    */
export function loadJson(url: string): any {
    let jsonObject: any;

    $.ajax({
        url: url,
        dataType: "json",
        async: false,
        success: (scr, status, xhr) => {
            jsonObject = scr;
        },
        error: (xhr, status, err) => {
            throw new Error(`${url}加载异常, 状态码: ${xhr.status} , 错误描述 : ${err}`);
        }
    });

    return jsonObject;
}
/**
* 动态加载文本
* @param url 待加载文本的url
* @remark url必须是../开头的相对地址
*/
export function loadText(url: string): any {
    let text: string;

    $.ajax({
        url: url,
        dataType: "text",
        async: false,
        success: (scr, status, xhr) => {
            text = scr;
        },
        error: (xhr, status, err) => {
            throw new Error(`${url}加载异常, 状态码: ${xhr.status} , 错误描述 : ${err}`);
        }
    });

    return text;
}

/**
    * 动态加载 link 标签
    * @param url 待加载文件的url
    * @param type 文件类型
    * @param rel 
    */
export function loadLink(url: string, type: string, rel: string) {
    var link = document.createElement("link");
    link.type = type;
    link.rel = rel;
    link.href = url;
    document.getElementsByTagName("head")[0].appendChild(link);
}

/**
 * html
 * @param html 元素
 */
export function loadElement(html: string): Element {
    let element = document.createElement("div");
    element.innerHTML = html;
    return $(element).children[0];
}


/**
 * 获取URL对应KEY的参数值
 * @param key URL参数KEY
 */
export function getUrlParamByKey(key: string) {
    let reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
    let r = window.location.search.substr(1).match(reg);
    if (r != null)
        return decodeURI(r[2]);   //对参数进行decodeURI解码
    return null;
}

/**
 * 远程工厂: 通过JSON实现远程调用
 */
@platform.addon("远程工厂",
    "通过JSON实现远程调用",
    moduleName)
export class remoteFactory extends platform.proxyFactory {
    constructor(public objectType: new () => any, public url: string, public serviceName: string) {
        super(objectType);
    }

    proxyMethod?(methodName: any, args: any): any {
        return jsonCall(this.url, this.serviceName, methodName, args);
    }
}

/**
 * 异步工厂
 * @remark 通过Promise对象进行远程调用的工厂
 */
@platform.addon("异步工厂", "通过Promise对象进行远程调用的工厂", moduleName)
export class asyncFactory extends platform.proxyFactory {
    constructor(public objectType: new () => any, public url: string, public serviceName: string) {
        super(objectType);
    }
    proxyMethod?(methodName: any, args: any): any {
        let that = this;
        // 返回Promise对象
        return new Promise((resolve, reject) => {
            asyncJsonCall(that.url, that.serviceName, methodName, args,
                (result) => {
                    resolve(result);
                },
                (error) => {
                    reject(error);
                });
        });
    }
}


/**
 * 将html设置到容器中
 * @param html 控件html
 * @param css 控件风格
 */
export function setTo(container: string | Element | JQuery, html?: string, css?: string): baseControl {
    let control = new baseControl(html, css);
    control.setTo(container);
    return control;
}

/**
 * 将html添加到容器中 
 * @param html 控件html
 * @param css 控件风格
 */
export function appendTo(container: string | Element | JQuery, html?: string, css?: string): baseControl {
    let control = new baseControl(html, css);
    control.appendTo(container);
    return control;
}

//******************控件******************//
/**
 * 模板装饰器
 * @param html 模板内容
 * @param css 样式
 */
export function template(html?: string, css?: string) {
    return function (target: any) {
        target.prototype.html = html;
        target.prototype.css = css;
    };
}

/**
 * 控件基类
 */
@platform.addon("控件基类", "可以作为子对象插入到容器中的控件对象", moduleName)
export class baseControl extends platform.baseObject {
    /**
     * 标签类型
     */
    tagType?: string = "div";
    /**
     * 视图模板
     */
    html?: string;
    /**
     * 视图样式文件
     */
    css?: string;
    /** 元素样式 */
    private styles?: any = {};

    constructor(html?: string, css?: string) {
        super();
        if (html)
            this.html = html;
        if (css)
            this.css = css;
    }

    /**
     * 元素
     */
    element?: Element;
    /**
     * 绑定前事件
     */
    onBeforeBind?() {
    };
    /**
     * 绑定后事件
     */
    onAfterBind?() {
    };
    /**
     * 事件：渲染前
     */
    onBeforeRender?() {
    };
    /**
     * 事件：渲染后
     */
    onAfterRender?() {
    };

    /**
     * 事件：显示后
     */
    onShowed?() {

    };

    /**
     * 渲染到容器
     * @param container 容器控件 
     */
    render?(container?: string | Element | JQuery, append: boolean = false): void {
        if (this.onBeforeRender) {
            this.onBeforeRender();
        }
        // 将html插入容器
        if (this.html) {
            let html = this.html;
            // 用~开头的是模板
            if (!html.startsWith("<")) {
                // 加载文件
                try {
                    html = loadText(html);
                } catch (err) {
                    // 如果加载html文件错误，则仍让当作普通html渲染
                    platform.log(err);
                }
            }

            let div = document.createElement(this.tagType);
            div.innerHTML = html;

            if (div.children.length > 1) {
                this.element = div;
            } else {
                this.element = div.children[0];
            }

            if (!append) {
                $(container).empty();
            }
            $(container).append(this.element);
        }
        // 加载css
        if (this.css) {
            loadStyle(this.css);
        }
        this.setStyles();
        this.rebind();
        if (this.onAfterRender) {
            this.onAfterRender();
        }
    }

    /**
     * 绑定到元素
     * @param element 元素
     */
    bindTo?(element: Element) {
        if (this.onBeforeRender) {
            this.onBeforeRender();
        }

        this.element = element;

        this.rebind();
        if (this.onAfterRender) {
            this.onAfterRender();
        }
    }

    /**
     * 查找子控件
     * @param elementName 元素
     */
    findByName?(elementName: string): JQuery {
        return this.find(`[name='${elementName}']`);
    }

    find?(elementName: string): JQuery {
        return $(this.element).find(elementName);
    }

    /**
     * 添加到容器中
     * @param container 容器
     */
    appendTo?(container: string | Element | JQuery) {
        this.render(container, true);
    }

    /**
     * 重新绑定
     */
    rebind?() {
        if (this.onBeforeBind) {
            this.onBeforeBind();
        }

        if (this.element) {
            for (let propertyName in this) {
                if (propertyName.startsWith("$")) {
                    let controlName = propertyName.substr(1);
                    this[propertyName] = this.findByName(controlName);
                }
            }
        }

        // 绑定控件
        if (this.onAfterBind) {
            this.onAfterBind();
        }
    }

    /**
     * 增加风格类型
     * @param className 风格类型
     */
    addClass?(className: string) {
        $(this.element).addClass(className);
    }

    /**
     * 特性获取/设定
     * @param name 特性名称
     * @param value 特性值，如果不输入，则表示返回
     */
    attr?(name: string, value?: any): any {
        return $(this.element).attr(name, value);
    }

    /**
     * 风格获取/设定
     * @param name 风格名称
     * @param value 风格值，如果不输入，则表示返回
     */
    style?(name?: string, value?: any): any {
        this.styles[name] = value;
        return this;
    }
    /**
     * 风格设置
     */
    setStyles?() {
        for (let name in this.styles) {
            let value = this.styles[name];
            $(this.element).css(name, value);
        }
    }
}

@platform.addon("菜单", "菜单类", moduleName)
export class menu extends platform.baseObject {
    /**
     * 菜单标题
     */
    caption?: string;
    /**
     * 子菜单
     */
    childMenus?: menu[];
    /**
     * 点击事件
     */
    onClick?: () => void;
}

/**
 * 参数支持接口
 * @description 视图获取外部参数的接口定义
 */
export interface supportParameters {
    /** 参数键值列表 */
    requestParameterKeys?: string[];
    /** 获取参数键值列表 */
    getParameterKeys?(): string[];
    /** 设置参数值 */
    setRequestParameterValue?(paramValues: any[string]);
}

/** 判断控件是否支持参数输入 */
export function isSupportParameters(control: baseControl):
    control is supportParameters {
    return (<supportParameters>control).getParameterKeys != undefined
        && (<supportParameters>control).setRequestParameterValue != undefined;
}

/**
 * 视图基类
 */
@platform.addon("视图基类", "所有视图的基类，视图中包含一个菜单", moduleName)
export class baseView extends baseControl {
    /**
     * 标题
     */
    caption?: string;
    /**
     * 菜单
     */
    menus?: menu[];
}

/**
 * 视图栈
 * @author chencx（陈楚溪）
 */
export class viewStack {
    /** 视图导航缓存数组 */
    private pages: baseView[] = [];

    /**
     * 入栈
     * @param page 视图
     */
    push(page: baseView) {
        return this.pages.push(page);
    }

    /**
     * 出栈
     * @return 视图
     */
    pop(): baseView {
        return this.pages.pop();
    }

    /**
     * 获取栈顶
     * @return 视图
     */
    top(): baseView {
        let len = this.pages.length;
        if (len > 0)
            return this.pages[len - 1];
        return undefined;
    }

    /**
     * 获取栈长度
     * @return 长度
     */
    length(): number {
        return this.pages.length;
    }

    /**
     * 清空视图栈
     */
    empty(): void {
        this.pages.splice(0, this.pages.length);
    }
}

/**
* 标签页接口
* @author chencx（陈楚溪）
*/
export interface iTabPage extends baseControl {
    /** 标题 */
    title?: string;
    /** 图标 */
    icon?: string;
    /** 图标样式 */
    iconClass?: string;
    /** 视图 */
    view?: baseControl | platform.factory;
    /** 视图栈 */
    viewStack?: viewStack;
}

/**
 * 主窗体基类
 */
@platform.addon("主窗体基类", "所有主窗体的基类", moduleName)
export class baseMainForm extends baseControl {
    /** 当前标签页 */
    currentTabPage: iTabPage;

    /** 当前视图栈 */
    protected currentViewStack: viewStack;

    /** 当前视图 */
    currentView: baseView;

    /**
    * 更改标签页，初始化标签页视图栈
    * @param page 标签页
    */
    changePage?(page: iTabPage): void {
        // 存在视图栈，说明将该标签页关联视图作为首页
        if (page.viewStack) {
            this.currentTabPage = page;
            this.currentViewStack = page.viewStack;
        }
        let view: baseView = platform.getObject(page.view);
        if (page.title)
            view.caption = page.title;
        this.currentViewStack.empty();
        this.navigate(view);
    }

    /**
     * 导航到视图，如果视图是string类型，表示url，如果是baseView，表示直接导航到对象
     * 1.保留当前视图，跳转到应用内的某个视图。
     * 2.视图栈表现：新视图入栈。
     * @param view 视图
     * @param caption 标题
     * @param args 参数
     */
    navigate?(view: string | baseView, caption?: string, args?: any[string]): void {
        let targetView: baseView = this.getView(view, caption);
        if (!targetView)
            throw new Error(`加载视图${targetView}失败`);
        if (args) {
            this.setViewRequest(targetView, args);
        }
        this.currentViewStack.push(targetView);
        this.openView(targetView);
    }

    /**
     * 导航返回视图
     * 1.关闭当前视图，返回上一视图或多级视图。
     * 2.视图栈表现：
     *   2.1.levelOrView为number时，代表返回的视图层级，默认值为1；视图不断出栈，直到目标返回视图，新视图入栈；如果大于现有视图数，则返回到第一个视图；
     *   2.2.levelOrView为baseView时，代表返回的视图对象，视图不断出栈，直到第一个目标视图，新视图入栈；如果视图在栈中不存在，则作为第一个视图入栈。
     * @param levelOrView 返回视图层级或对象
     *                    ，
     */
    navigateBack?(levelOrView: number | baseView = 1): void {
        let targetView;
        if (typeof levelOrView == 'number') {
            let level = levelOrView;
            if (level > this.currentViewStack.length() - 1) {
                level = this.currentViewStack.length() - 1;
            }
            for (let i: number = 0; i <= level; i++) {
                targetView = this.currentViewStack.pop();
            }
        } else {
            targetView = levelOrView;
            let historyView;
            while (historyView = this.currentViewStack.pop()) {
                if (targetView == historyView) {
                    break;
                }
            }
        }
        this.currentViewStack.push(targetView);
        this.openView(targetView);
    }

    /**
     * 导航到首页
     * 1.关闭当前视图，返回第一个视图。
     * 2.视图栈表现：视图不断出栈，直到第一个视图。
     */
    navigateHome?(): void {
        let targetView;
        let len = this.currentViewStack.length();
        if (len < 1)
            throw new Error('加载首页失败，视图栈为空');
        else if (len == 1) {
            targetView = this.currentViewStack.top();
        } else {
            for (let i: number = 0; i < len - 1; i++) {
                let targetView = this.currentViewStack.pop();
            }
            targetView = this.currentViewStack.top();
        }
        this.openView(targetView);
    }

    /**
     * 打开视图
     * @param view 视图
     */
    protected openView?(view: baseView): void {
        this.currentView = view;
    }

    /**
     * 获取视图
     */
    getView?(view: string | baseView, caption?: string): baseView {
        let targetView: baseView;
        if (typeof view == "string") {
            if (view.endsWith(".html")) {
                // 加载html
                targetView = new baseView();
                targetView.html = view;
                if (caption) {
                    targetView.caption = caption;
                }
            } else {
                // 加载对象
                targetView = syncRequire(view).defaultObject;
            }
        } else {
            targetView = view;
        }
        return targetView;
    }

    /** 设置视图请求参数 */
    setViewRequest?(view: baseView, args?: any[string]) {
        if (isSupportParameters(view) && args) {
            let request = {};
            let keys = view.getParameterKeys();
            if (keys) {
                for (let key of keys) {
                    let value = args[key];
                    if (value) {
                        request[key] = value;
                    }
                }
                view.setRequestParameterValue(request);
            }
        }
    }
}

/**
 * 包含cookie的相关操作方法
 */
export class cookie {
    /**
     * 获取cookie的值
     * @param name cookie名称
     */
    static getCookie(name: string) {
        var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
        if (arr = document.cookie.match(reg))
            return decodeURIComponent(arr[2]);
        else
            return undefined;
    }

    /**
     * 删除cookie
     * @param name cookie名称
     */
    static delCookie(name: string) {
        var exp = new Date();
        exp.setTime(exp.getTime() - 1);
        var cval = this.getCookie(name);
        if (cval != undefined)
            document.cookie = name + "=" + cval + ";expires=" + exp.toUTCString();
    }

    /**
     * 设置cookie
     * @param name cookie名称
     * @param value cookie值
     * @param time cookie储存的时间（使用示例：s20是代表20秒；h是指小时，如12小时则是：h12；d是天数，30天则：d30 ）
     */
    static setCookie(name?: string, value?: string, time?: string) {
        if (time) {
            var strsec = this.getsec(time);
            var exp = new Date();
            exp.setTime(exp.getTime() + strsec * 1);
            document.cookie = name + "=" + encodeURIComponent(value) + ";expires=" + exp.toUTCString();
        } else {
            document.cookie = name + "=" + encodeURIComponent(value) + ";";
        }
    }
    static getsec(str: string) {
        var str1 = parseInt(str.substring(1, str.length)) * 1;
        var str2 = str.substring(0, 1);
        if (str2 == "s") {
            return str1 * 1000;
        }
        else if (str2 == "h") {
            return str1 * 60 * 60 * 1000;
        }
        else if (str2 == "d") {
            return str1 * 24 * 60 * 60 * 1000;
        }
    }
}


//******************应用******************//

/**
 * 名称:加载效果(过度界面)
 * @description 数据加载画面
 * @author 胡燕龙(huyl)
 */
@platform.addon('加载效果(过度界面)', '数据加载画面', moduleName)
export class loadObject extends platform.baseObject {
    /** 
     * 加载图标
     * @description 一个16×16或者32×32的base64的gif图片
     */
    icon?: string;
    /** 是否显示 */
    private show?: boolean = false;
    /** 加载效果(过度界面) */
    constructor() {
        super();
    }
    /** 显示加载效果 */
    showLoading?(text?: string) {
        if (this.show) return;
        let option = {};
        if (this.icon) {
            option['icon'] = this.icon;
        }
        if (text) {
            option['text'] = text;
        }
        $("body").mLoading(option);
        this.show = true;
    }
    /** 隐藏加载效果 */
    hideLoading?() {
        if (!this.show) return;
        $("body").mLoading('hide');
        this.show = false;
    }
}

/**
 * 提示类型
 */
export enum alertType {
    'error',
    'warning',
    'information'
}

/**
 * 名称:提示
 * @description 用于提示信息
 * @author 胡燕龙(huyl)
 */
@platform.addon('提示信息', '用于提示信息', moduleName)
export class confirmObject extends platform.baseObject {
    isAlert?: boolean = false;
    /** 提示信息 */
    constructor() {
        super();
    }
    /**
     * 消息提示
     * @param title 标题
     * @param message 消息
     * @param msgType 消息类型
     */
    alerts(title: string, message: string, msgType: alertType = alertType.information) {
        if (this.isAlert) return;
        this.isAlert = true;
        let icon = "", color = "";
        if (msgType == alertType.error) {
            icon = 'glyphicon glyphicon-warning-sign', color = 'red';
        }
        if (msgType == alertType.warning) {
            icon = 'glyphicon glyphicon-warning-sign', color = 'orange';
        }
        if (msgType == alertType.information) {
            icon = 'glyphicon glyphicon-info-sign', color = 'blue';
        }
        let that = this;
        $.alert({
            title: title,
            content: message,
            icon: icon,
            type: color,
            typeAnimated: true,
            animation: 'Rotate',
            closeAnimation: 'Rotate',
            animateFromElement: false,
            animationBounce: 1.5,
            buttons: {
                confirm: {
                    text: '确认',
                    action: function () {
                        that.isAlert = false;
                    }
                }
            }
        });
    }

    /**
     * 确认提示
     * @param title 标题
     * @param message 确认信息
     */
    confirm(title: string, message: string): boolean {
        return true;
    }
}

/**
 * 主应用程序
 */
export let mainApplication: clientApplication;

/**
 * 客户端应用
 */
@platform.addon("客户端应用设置", "包含各种资源的客户端应用实体对象", moduleName)
export class clientApplication extends appCommon.application {
    /** 主窗体 */
    mainForm?: baseMainForm;
    /** 加载效果 */
    load?: loadObject;
    /** 提示 */
    alert?: confirmObject;

    start(): void {
        super.start();
        mainApplication = this;
        // 创建默认加载效果
        if (!this.load) {
            this.load = new loadObject();
        }
        // 创建默认提示效果
        if (!this.alert) {
            this.alert = new confirmObject();
        }
        this.load.showLoading('启动中...');
        if (this.mainForm) {
            this.mainForm.render("#main_form_container");
        }
        this.load.hideLoading();
    }
}

/**
 * 启动客户端
 * @param clientApp 客户端应用
 * @param onLoad 加载事件
 * @param onError 错误事件
 */
export function startClient(clientApp: clientApplication, onLoad?: () => void, onError?: () => void) {
    window.onload = () => {
        platform.log("页面重新加载");
        clientApp.start();

        // 窗体加载后的动作
        if (onLoad)
            onLoad();
    };

    window.onerror = (err) => {
        if (onError) {
            onError();
        } else {
            // 未知异常记录到服务器上
            platform.logToServer(err, "error");
        }
    }
}

/** 
 * 显示加载效果
 * @param text 提示内容
 */
export function showLoading(text?: string) {
    if (!mainApplication) return;
    mainApplication.load.showLoading(text);
}

/**
 * 隐藏加载效果
 */
export function hideLoading() {
    if (!mainApplication) return;
    setTimeout(() => {
        mainApplication.load.hideLoading();
    }, 500);
}

/**
 * 消息提示
 * @param title 标题
 * @param message 消息
 * @param msgType 消息类型
 */
export function alerts(title: string, message: string,
    msgType: alertType = alertType.information) {
    if (!mainApplication) return;
    mainApplication.alert.alerts(title, message, msgType);
}